﻿using System;
using System.DirectoryServices;
using System.Text.RegularExpressions;

namespace Framework.IISUtility
{
    public class IISCommon
    {
        /// <summary>
        /// 获取最小ID，越小越好
        /// </summary>
        /// <returns></returns>
        public int SiteId()
        {
            var root = new DirectoryEntry("IIS://localhost/W3SVC");
            // Find unused ID value for new web site
            int siteId = 1;
            foreach (DirectoryEntry e in root.Children)
            {
                if (e.SchemaClassName == "IIsWebServer")
                {
                    int id = Convert.ToInt32(e.Name);
                    if (id >= siteId)
                    {
                        siteId = id + 1;
                    }
                }
            }
            return siteId;
        }

        #region 建IIS站点

        /// <summary>
        /// IIS站点
        /// </summary>
        /// <param name="port">站点端口</param>
        /// <param name="siteName">站点ID</param>
        /// <param name="siteExplain">域名</param>
        /// <param name="defaultDoc">默认文档</param>
        /// <param name="pathToRoot"> </param>
        /// <param name="userId"> </param>
        public int CreateSite(string port, string siteName, string siteExplain, string defaultDoc, string pathToRoot,
                              string userId)
        {
            int mark;
            try
            {
                // createAppPool(siteExplain);
                var de = new DirectoryEntry("IIS://localhost/" + "w3svc"); //从活动目录中获取IIS对象。  
                var prams = new object[] { "IIsWebServer", Convert.ToInt32(siteName) };
                var site = (DirectoryEntry)de.Invoke("Create", prams); //创建IISWebServer对象。  
                site.Properties["KeyType"][0] = "IIsWebServer";
                site.Properties["ServerComment"][0] = siteExplain; //站点说明  
                site.Properties["ServerState"][0] = 2; //站点初始状态，1.停止，2.启动，3  
                site.Properties["ServerSize"][0] = 1;
                site.Properties["ServerBindings"].Add(":" + port + ":" + siteExplain); //站点端口  
                site.CommitChanges(); //保存改变
                de.CommitChanges();
                DirectoryEntry root = site.Children.Add("Root", "IIsWebVirtualDir"); //添加虚拟目录对象  
                root.Invoke("AppCreate", true); //创建IIS应用程序  
                root.Invoke("AppCreate3", new object[] { 2, userId, true });
                //创建应用程序池，并指定应用程序池为"HostPool","true"表示如果HostPool不存在，则自动创建
                root.Properties["path"][0] = pathToRoot; //虚拟目录指向的物理目录  
                root.Properties["EnableDirBrowsing"][0] = true; //目录浏览  
                root.Properties["AuthAnonymous"][0] = true;
                root.Properties["AccessExecute"][0] = true; //可执行权限  
                root.Properties["AccessRead"][0] = true;
                root.Properties["AccessWrite"][0] = true;
                root.Properties["AccessScript"][0] = true; //纯脚本  
                root.Properties["AccessSource"][0] = false;
                root.Properties["FrontPageWeb"][0] = false;
                root.Properties["KeyType"][0] = "IIsWebVirtualDir";
                root.Properties["AppFriendlyName"][0] = siteExplain; //应用程序名   
                root.Properties["AppIsolated"][0] = 2;
                root.Properties["DefaultDoc"][0] = defaultDoc; //默认文档  
                root.Properties["EnableDefaultDoc"][0] = true; //是否启用默认文档  
                root.CommitChanges();
                site.CommitChanges();
                root.Close();
                site.Close();
                de.CommitChanges(); //保存  
                site.Invoke("Start", null); //除了在创建过程中置初始状态外，也可在此调用方法改变状态  
                mark = 1;
            }
            catch
            {
                mark = 0;
            }
            return mark;
        }

        #endregion

        #region 域名绑定方法

        public int AddHostHeader(int siteid, string ip, int port, string domain) //增加主机头（站点编号.ip.端口.域名）
        {
            int mark;
            try
            {
                var site = new DirectoryEntry("IIS://localhost/W3SVC/" + siteid);
                PropertyValueCollection serverBindings = site.Properties["ServerBindings"];
                string headerStr = string.Format("{0}:{1}:{2}", ip, port, domain);
                if (!serverBindings.Contains(headerStr))
                {
                    serverBindings.Add(headerStr);
                }
                site.CommitChanges();
                mark = 1;
            }
            catch
            {
                mark = 0;
            }
            return mark;
        }

        #endregion

        #region 删除主机头

        public void DeleteHostHeader(int siteid, string ip, int port, string domain) //删除主机头（站点编号.ip.端口.域名）
        {
            var site = new DirectoryEntry("IIS://localhost/W3SVC/" + siteid);
            PropertyValueCollection serverBindings = site.Properties["ServerBindings"];
            string headerStr = string.Format("{0}:{1}:{2}", ip, port, domain);
            if (serverBindings.Contains(headerStr))
            {
                serverBindings.Remove(headerStr);
            }
            site.CommitChanges();
        }

        #endregion

        #region 删除站点

        public void DelSite(string siteName)
        {
            string siteNum = GetWebSiteNum(siteName);
            string siteEntPath = String.Format("IIS://{0}/w3svc/{1}", "localhost", siteNum);
            var siteEntry = new DirectoryEntry(siteEntPath);
            string rootPath = String.Format("IIS://{0}/w3svc", "localhost");
            var rootEntry = new DirectoryEntry(rootPath);
            rootEntry.Children.Remove(siteEntry);
            rootEntry.CommitChanges();
        }

        public string GetWebSiteNum(string siteName)
        {
            var regex = new Regex(siteName);
            string entPath = String.Format("IIS://{0}/w3svc", "localhost");
            var ent = new DirectoryEntry(entPath);
            foreach (DirectoryEntry child in ent.Children)
            {
                if (child.SchemaClassName == "IIsWebServer")
                {
                    string tmpStr;
                    if (child.Properties["ServerBindings"].Value != null)
                    {
                        tmpStr = child.Properties["ServerBindings"].Value.ToString();
                        if (regex.Match(tmpStr).Success)
                        {
                            return child.Name;
                        }
                    }
                    if (child.Properties["ServerComment"].Value != null)
                    {
                        tmpStr = child.Properties["ServerComment"].Value.ToString();
                        if (regex.Match(tmpStr).Success)
                        {
                            return child.Name;
                        }
                    }
                }
            }
            return "没有找到要删除的站点";
        }

        #endregion

        #region 创建应用程序池

        public static void CreateAppPool(string appPoolName)
        {
            var apppools = new DirectoryEntry("IIS://localhost/W3SVC/AppPools");
            DirectoryEntry newpool = apppools.Children.Add(appPoolName, "IIsApplicationPool");
            newpool.CommitChanges();
        }

        #endregion

        #region 删除应用程序池

        public void DeleteAppPool(string appPoolName)
        {
            bool existAppPoolFlag = false;
            try
            {
                var apppools = new DirectoryEntry("IIS://localhost/W3SVC/AppPools");
                foreach (DirectoryEntry a in apppools.Children)
                {
                    if (a.Name == appPoolName)
                    {
                        existAppPoolFlag = true;
                        a.DeleteTree();
                        // MessageBox.Show("应用程序池名称删除成功", "删除成功");
                    }
                }
                if (existAppPoolFlag == false)
                {
                    // MessageBox.Show("应用程序池未找到", "删除失败");
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        #endregion
    }
}